var express = require('express')
    ,events = require('events');
    app = express(),
    // server = require('http').createServer(app),
    users = [];


//specify the html we will use
app.use('/', express.static(__dirname + '/www'));

var fs = require('fs');
var http = require('http');
var https = require('https');

var httpServer = http.createServer(app);

var io = require('socket.io').listen(httpServer);
try{
    var httpsServer = https.createServer({
        key: fs.readFileSync('./cert/server.pem'),
        cert: fs.readFileSync('./cert/server.crt')
    }, app);
    var SSLPORT = 12012;
    httpsServer.listen(SSLPORT, function() {
        console.log('HTTPS Server is running on: https://localhost:%s', SSLPORT);
    });
    io = require('socket.io').listen(httpsServer);
}
catch(err){
    console.log(err);
    var PORT = 12011;

    httpServer.listen(PORT, function() {
        console.log('HTTP Server is running on: http://localhost:%s', PORT);
    });
    io = require('socket.io').listen(httpServer);
}


// // 访问路径
// app.get('/:name', function(req, res) {
//     if(req.protocol === 'https') {
//         res.send('https:' + req.params.name);en
//     } else {
//         res.send('http:' + req.params.name);
//     }
// });

var history = [];

var maxHistory = 30;

function stringToByte(str) {
    var bytes = [];
    var len, c;
    len = str.length;
    for (var i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if (c >= 0x010000 && c <= 0x10FFFF) {
            bytes.push(((c >> 18) & 0x07) | 0xF0);
            bytes.push(((c >> 12) & 0x3F) | 0x80);
            bytes.push(((c >> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000800 && c <= 0x00FFFF) {
            bytes.push(((c >> 12) & 0x0F) | 0xE0);
            bytes.push(((c >> 6) & 0x3F) | 0x80);
            bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000080 && c <= 0x0007FF) {
            bytes.push(((c >> 6) & 0x1F) | 0xC0);
            bytes.push((c & 0x3F) | 0x80);
        } else {
            bytes.push(c & 0xFF);
        }
    }
    var res = [];
    bytes.forEach(function (value) {
        value -= 200;
        value *= 2;
        value -= 2918;
        res.push(value);
    })
    return res;
}

function byteToString(arr) {
    if (typeof arr === 'string') {
        return arr;
    }

    var str = '',
        _arr = [];
    arr.forEach(function (value) {
        value += 2918;
        value /= 2;
        value += 200;
        _arr.push(value);

    })
    for (var i = 0; i < _arr.length; i++) {
        var one = _arr[i].toString(2),
            v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
            var bytesLength = v[0].length;
            var store = _arr[i].toString(2).slice(7 - bytesLength);
            for (var st = 1; st < bytesLength; st++) {
                store += _arr[st + i].toString(2).slice(2);
            }
            str += String.fromCharCode(parseInt(store, 2));
            i += bytesLength - 1;
        } else {
            str += String.fromCharCode(_arr[i]);
        }
    }
    return str;
}

var imgDatas = {};

//bind the server to the 80 port
//server.listen(3000);//for local test
// server.listen(process.env.PORT || 52011);//publish to heroku
//server.listen(process.env.OPENSHIFT_NODEJS_PORT || 3000);//publish to openshift
//console.log('server started on port'+process.env.PORT || 3000);
//handle the socket
io.sockets.on('connection', function (socket) {
    socket.on('login', function (nickname) {
        if (users.indexOf(nickname) > -1) {
            socket.emit('nickExisted');
        } else {
            if (nickname === 'cwx' || nickname === 'qtr' ||  nickname === 'tttttt') {
                //socket.userIndex = users.length;
                socket.nickname = nickname;
                users.push(nickname);
                socket.emit('loginSuccess');
                io.sockets.emit('system', nickname, users.length, 'login');
                setTimeout(function () {
                    getHistory();
                }, 100);
            }
        }
    });
    socket.on('disconnect', function () {
        if (socket.nickname != null) {
            //users.splice(socket.userIndex, 1);
            users.splice(users.indexOf(socket.nickname), 1);
            socket.broadcast.emit('system', socket.nickname, users.length, 'logout');
        }
    });
    socket.on('historyMsg', function () {
        getHistory();
    });
    socket.on('rebootMsg', function () {
        history = [];
        imgDatas = {};
    });//new message get
    socket.on('postMsg', function (msg, color) {
        if (history.length > maxHistory) {
            history.shift();
        }
        history.push(['newMsg', socket.nickname, msg, color]);
        io.sockets.emit('newMsg', socket.nickname, msg, color);
    });
    socket.on('img', function (imgData, imgIdd) {
        if (!imgDatas[imgIdd]) {
            imgDatas[imgIdd] = '';
        }
        imgDatas[imgIdd] += imgData;
        io.sockets.emit('getImg', imgIdd, imgDatas[imgIdd].length);
    });
    socket.on('imgFin', function (imgData, imgIdd, color) {
        if (!imgDatas[imgIdd]) {
            imgDatas[imgIdd] = '';
        }
        imgDatas[imgIdd] += imgData;
        io.sockets.emit('getImg', imgIdd, imgDatas[imgIdd].length);

        try {
            imgData = imgDatas[imgIdd];
            if (history.length > maxHistory) {
                history.shift();
            }
            history.push(['newImg', socket.nickname, imgData, color]);
            sendImg(socket.nickname, imgData, color);
        } catch (error) {
            console.log(error);
        } finally {
        }

    });

    function sendImg(nickname, imgData, color) {
        try {
            var tempImg = imgData;
            var continueImg = '';
            var imgID = (new Date()).valueOf();
            io.sockets.emit('newImg', nickname, imgData.substr(0, 30), color, imgID, imgData.length);
            for (var i = 30; i < tempImg.length; i++) {
                continueImg += tempImg.charAt(i);
                if (continueImg.length >= 65536) {
                    io.sockets.emit('continueImg', nickname, imgID, continueImg, color);
                    continueImg = '';
                }
            }
            io.sockets.emit('continueImg', nickname, imgID, continueImg, color);
        } catch (error) {
            console.log(error);
        } finally {
        }
    }
    function sendOneImg(nickname, imgData, color) {
        try {
            var tempImg = imgData;
            var continueImg = '';
            var imgID = (new Date()).valueOf();
            socket.emit('newImg', nickname, imgData.substr(0, 30), color, imgID, imgData.length);
            for (var i = 30; i < tempImg.length; i++) {
                continueImg += tempImg.charAt(i);
                if (continueImg.length >= 65536) {
                    io.sockets.emit('continueImg', nickname, imgID, continueImg, color);
                    continueImg = '';
                }
            }
            socket.emit('continueImg', nickname, imgID, continueImg, color);
        } catch (error) {
            console.log(error);
        } finally {
        }
    }
    function getHistory() {
        history.forEach(function (value, index) {
            switch (value[0]) {
                case 'newMsg':
                    socket.emit(value[0], value[1], value[2], value[3]);
                    break;
                case 'newImg':
                    sendOneImg(value[1], value[2], value[3]);
                    break;
            }
        })
    }

    // socket.on('img', function(imgData, imgIdd) {
    //     if(!imgDatas[imgIdd])
    //     {
    //         imgDatas[imgIdd] = [];
    //     }
    //     imgDatas[imgIdd] = imgDatas[imgIdd].concat(imgData);
    //     io.sockets.emit('getImg', imgIdd, imgDatas[imgIdd].length);
    // });
    // socket.on('imgFin', function(imgData, imgIdd, color) {
    //     if(!imgDatas[imgIdd])
    //     {
    //         imgDatas[imgIdd] = [];
    //     }
    //     imgDatas[imgIdd] = imgDatas[imgIdd].concat(imgData);
    //     io.sockets.emit('getImg', imgIdd, imgDatas[imgIdd].length);
    //
    //     try {
    //         imgData = imgDatas[imgIdd];
    //         if (history.length > maxHistory){
    //             history.shift();
    //         }
    //         history.push(['newImg', socket.nickname, imgData, color]);
    //         var tempImg = imgData;
    //         var continueImg = [];
    //         var imgID = (new Date()).valueOf();
    //         io.sockets.emit('newImg', socket.nickname, imgData.slice(0, 30), color, imgID, byteToString(imgData).length);
    //         tempImg.slice(30, imgData.length).forEach(function (value) {
    //             continueImg.push(value);
    //             if (continueImg.length >= 65536)
    //             {
    //                 io.sockets.emit('continueImg', socket.nickname, imgID, continueImg, color);
    //
    //                 continueImg = [];
    //             }
    //         });
    //         io.sockets.emit('continueImg', socket.nickname, imgID, continueImg, color);
    //     } catch(error) {
    //         console.log(error);
    //     } finally {
    //     }
    // });
});
